/**
 * 
 */
package cn.edu.bjtu.alex.rewrite.components;

import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;


import cn.edu.bjtu.alex.rewrite.Context;
import cn.edu.bjtu.alex.rewrite.interfaces.Term;
import cn.edu.bjtu.alex.rewrite.interfaces.TermFeatureable;
import cn.edu.bjtu.alex.rewrite.interfaces.impl.FeaturedTerm;
import cn.edu.bjtu.alex.rewrite.tools.MetricUtils;

/**
 * 计算文档的TFIDF值
 * @author alex
 *
 */
public class CalcTFIDF extends BaseComponent{
	private Set<TermFeatureable> featuredTerms;
	/**
	 * @param ctx
	 */
	public CalcTFIDF(Context ctx) {
		super(ctx);
		// TODO Auto-generated constructor stub
	}

	@Override
	protected void fitInternal() {
		featuredTerms = ctx.featuredTerms();
		// for each document, compute TF, IDF, TF-IDF
		//label doc words
		Iterator<Entry<String, Map<String, Map<String, Term>>>> iter = ctx.termTableIterator();
		while(iter.hasNext()) {
			Entry<String, Map<String, Map<String, Term>>> labelledDocsEntry = iter.next();
			String label = labelledDocsEntry.getKey();
			LOG.info("Compute TF-IDF for:label=" + label);
			Map<String, Map<String, Term>>  docs = labelledDocsEntry.getValue();
			Iterator<Entry<String, Map<String, Term>>> docsIter = docs.entrySet().iterator();
			while(docsIter.hasNext()) {
				Entry<String, Map<String, Term>> docsEntry = docsIter.next();
				String doc = docsEntry.getKey();
				Map<String, Term> terms = docsEntry.getValue();
				Iterator<Entry<String, Term>> termsIter = terms.entrySet().iterator();
				LOG.debug("label=" + label + ", doc=" + doc + ", terms=" + terms);
				while(termsIter.hasNext()) {
					Entry<String, Term> termEntry = termsIter.next();
					String word = termEntry.getKey();
					// check whether word is a featured word
					if(isFeaturedWord(word)) {
						Term term = termEntry.getValue();
						int freq = term.getFreq();
						//数据传递
						int termCount = ctx.termCount(label, doc);
						double tf = MetricUtils.tf(freq, termCount);
						int totalDocCount = ctx.totalDocCount();
						int docCountContainingTerm = ctx.docCount(term);
						double idf = MetricUtils.idf(totalDocCount, docCountContainingTerm);
							
						termEntry.getValue().setIdf(idf);
						termEntry.getValue().setTf(tf);
						termEntry.getValue().setTfidf(MetricUtils.tfidf(tf, idf));
						LOG.debug("Term detail: label=" + label + ", doc=" + doc + ", term=" + term);
					} else {
						termsIter.remove();
						LOG.debug("Not in CHI vector: word=" + word);
					}
				}
			}
			LOG.info("TF-IDF computed: label=" + label);
		}		
		
	}
	private boolean isFeaturedWord(String word) {
		return featuredTerms.contains(new FeaturedTerm(word));
	}

	/* (non-Javadoc)
	 * @see cn.edu.bjtu.alex.rewrite.components.BaseComponent#transformInternal()
	 */
	@Override
	protected void transformInternal() {
		// TODO Auto-generated method stub
		
	}
	

}
